package cn.skycity.common.controller;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.skycity.common.listener.SysUserImportListener;
import cn.skycity.common.service.ISysDeptService;
import cn.skycity.common.service.ISysRoleService;
import cn.skycity.common.service.ISysUserRoleService;
import cn.skycity.common.service.ISysUserService;
import cn.skycity.framework.core.model.Result;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.skycity.common.excel.core.ExcelResult;
import com.skycity.common.excel.utils.ExcelUtil;
import com.skycity.common.log.annotation.Log;
import com.skycity.common.log.enums.BusinessType;
import com.skycity.framework.uaa.pojo.dto.SysDeptBo;
import com.skycity.framework.uaa.pojo.dto.SysUserBo;
import com.skycity.framework.uaa.pojo.entity.SysUser;
import com.skycity.framework.uaa.pojo.entity.SysUserRole;
import com.skycity.framework.uaa.pojo.vo.SysUserImportVo;
import com.skycity.framework.uaa.pojo.vo.SysUserInfoVo;
import com.skycity.framework.uaa.pojo.vo.SysUserVo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.List;


@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Resource
    private ISysUserService sysUserService;
    @Resource
    private ISysDeptService deptService;
    @Resource
    private ISysUserRoleService iSysUserRoleService;
    @Resource
    private ISysRoleService iSysRoleService;
    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 用户分页列表
     * @param page
     * @param sysUser
     * @return
     */
    @GetMapping("/page")
    public Result<Page<SysUserVo>> page(Page<SysUserVo> page, SysUserBo sysUser) {
        return Result.success(sysUserService.selectPageList(page, sysUser));
    }

    /**
     * 根据用户名称获取用户详情
     * @param username
     * @return
     */
    @GetMapping("/username/{username}")
    public Result<SysUser> getUserByUsername(@PathVariable String username) {
        return Result.success(sysUserService.getByUsername(username));
    }

    @GetMapping("/deptTree")
    public Result<List<Tree<Long>>> deptTree(SysDeptBo dept) {
        return Result.success(deptService.selectDeptTreeList(dept));
    }

    /**
     * 根据用户ID获取用户详情
     * 编辑用户时调用
     * @param userId
     * @return
     */
    @GetMapping({"/", "/{userId}"})
    public Result<SysUserInfoVo> getUser(@PathVariable(value = "userId", required = false) Long userId) {
        SysUserInfoVo userInfoVo = new SysUserInfoVo();
        userInfoVo.setRoles(iSysRoleService.selectRoleList());
        if (ObjectUtil.isNotNull(userId)) {
            userInfoVo.setUser(sysUserService.selectUserById(userId));
            userInfoVo.setRoleIds(iSysUserRoleService.listRoleIdByUserId(userId));
        }
        return Result.success(userInfoVo);
    }

    /**
     * 修改用户
     * 同时保存用户角色关系
     * @param user
     * @return
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public Result<Void> edit(@Validated @RequestBody SysUserBo user) {
        if (!sysUserService.checkUserNameUnique(user)) {
            return Result.failed("修改用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StrUtil.isNotEmpty(user.getMobile()) && !sysUserService.checkMobileUnique(user)) {
            return Result.failed("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StrUtil.isNotEmpty(user.getEmail()) && !sysUserService.checkEmailUnique(user)) {
            return Result.failed("修改用户'" + user.getUserName() + "'失败，邮箱地址已存在");
        }
        int flag = sysUserService.updateUser(user);
        return Result.judge(flag);
    }

    /**
     * 添加用户
     * 同时保存用户角色关第
     * @param user
     * @return
     */
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping
    public Result<Void> add(@Validated @RequestBody SysUserBo user) {
        if (!sysUserService.checkUserNameUnique(user)) {
            return Result.failed("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StrUtil.isNotEmpty(user.getMobile()) && !sysUserService.checkMobileUnique(user)) {
            return Result.failed("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StrUtil.isNotEmpty(user.getEmail()) && !sysUserService.checkEmailUnique(user)) {
            return Result.failed("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        int flag = sysUserService.insertUser(user);
        return Result.judge(flag);
    }


    /**
     * 重置密码
     * @param user
     * @return
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public Result<Void> resetPwd(@RequestBody SysUserBo user) {
//        userService.checkUserAllowed(user.getUserId());
//        userService.checkUserDataScope(user.getUserId());
//        user.setPassword(BCrypt.hashpw(user.getPassword()));
//        userService.resetUserPwd(user.getUserId(), user.getPassword());
        return Result.success();
    }


    /**
     * 批量删除用户
     * @param userIds
     * @return
     */
    @DeleteMapping("/{userIds}")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> remove(@PathVariable Long[] userIds) {
        sysUserService.removeBatchByIds(Arrays.asList(userIds));
        iSysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, Arrays.asList(userIds)));
        return Result.success();
    }

    /**
     * 修改用户状态
     * @param user
     * @return
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public Result<Void> changeStatus(@RequestBody SysUserBo user) {
        sysUserService.update(new LambdaUpdateWrapper<SysUser>().set(SysUser::getStatus,user.getStatus())
                .eq(SysUser::getId,user.getId()));
        return Result.success();
    }

    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(SysUserBo user, HttpServletResponse response) {
        sysUserService.exportExcel(user,response);
    }

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil.exportExcel(List.of(), "用户数据", SysUserImportVo.class, response);
    }

    /**
     * 导入用户数据
     * @param file
     * @param updateSupport
     *  是否更新支持，如果已存在，则进行更新数据
     * @return
     * @throws Exception
     */
    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Result<String> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
        ExcelResult<SysUserImportVo> importResult = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport, passwordEncoder, sysUserService));
        return Result.success(importResult.getAnalysis());
    }

    /**
     * 获取部门下的所有用户
     * @param deptId
     * @return
     */
    @GetMapping("/list/dept/{deptId}")
    public Result<List<SysUser>> listByDeptId(@PathVariable Long deptId) {
        return Result.success(sysUserService.selectUserListByDept(deptId));
    }

}
